package com.deer.wms.ware.task.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.deer.wms.base.system.dao.ErpBackRecordMapper;
import com.deer.wms.base.system.model.Area.AreaInfo;
import com.deer.wms.base.system.model.Cell.CellInfo;
import com.deer.wms.base.system.model.ErpBackRecord;
import com.deer.wms.base.system.model.Shelf.ShelfInfo;
import com.deer.wms.base.system.model.erp.ErpInConstant;
import com.deer.wms.base.system.model.erp.ErpOutConstant;
import com.deer.wms.base.system.service.AreaInfoService;
import com.deer.wms.intercept.common.data.CurrentUser;
import com.deer.wms.inventory.constant.InventoryConstant;
import com.deer.wms.inventory.model.Inventory.InventoryTransact;
import com.deer.wms.inventory.service.InventoryService;
import com.deer.wms.inventory.service.InventoryTransactService;
import com.deer.wms.lzb.erp.service.ErpRecordService;
import com.deer.wms.project.root.core.result.CommonCode;
import com.deer.wms.project.root.exception.ServiceException;
import com.deer.wms.project.root.service.SuperServiceImpl;
import com.deer.wms.system.manage.service.CodeRuleService;
import com.deer.wms.system.manage.service.ValidatorService;
import com.deer.wms.ware.task.constant.WareTaskConstant;
import com.deer.wms.ware.task.dao.OutMasterMapper;
import com.deer.wms.ware.task.dao.SoDetailMapper;
import com.deer.wms.ware.task.model.*;
import com.deer.wms.ware.task.model.SO.SoDetail;
import com.deer.wms.ware.task.model.SO.SoMaster;
import com.deer.wms.ware.task.model.SO.SoMasterCriteria;
import com.deer.wms.ware.task.model.out.OutDetail;
import com.deer.wms.ware.task.model.out.OutMaster;
import com.deer.wms.ware.task.model.out.OutMasterDto;
import com.deer.wms.ware.task.model.pickTask.PickTask;
import com.deer.wms.ware.task.model.pushErp.StrategyErpService;
import com.deer.wms.ware.task.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import static com.deer.wms.project.root.util.CollectionUtils.convertMap;

/**
 * <p>
 * 发运单master 服务实现类
 * </p>
 *
 * @author luowei
 * @since 2022-04-18 17:42:23
 */
@Service
@Transactional
public class OutMasterServiceImpl extends SuperServiceImpl<OutMasterMapper, OutMaster> implements OutMasterService {
    @Autowired
    SoMasterService soMasterService;
    @Autowired
    SoDetailService soDetailService;
    @Autowired
    OutDetailService outDetailService;
    @Autowired
    ValidatorService validatorService;
    @Autowired
    InventoryService inventoryService;
    @Autowired
    InventoryTransactService inventoryTransactService;
    @Autowired
    OutMasterMapper outMasterMapper;
    @Autowired
    CodeRuleService codeRuleService;
    @Autowired
    private PickTaskService pickTaskService;
    @Autowired
    private SoDetailMapper soDetailMapper;
    @Autowired
    private ErpBackRecordMapper erpBackRecordMapper;
    @Autowired
    private AreaInfoService areaInfoService;
    @Value("${prj.name}")
    private String name;
    @Autowired
    private StrategyErpService strategyErpService;


    @Override
    public List<OutMasterDto> findList(SoMasterCriteria criteria) {
        return outMasterMapper.findList(criteria);
    }

    @Override
    public String createOutBill(SoMaster soMaster, Set<OutDetail> outDetails, CurrentUser currentUser) {
        //Step1.生成出库单out_master
        OutMaster outMaster = new OutMaster(soMaster);

        String billNo = codeRuleService.generateCodeByRedis("Out");
        outMaster.setBillNo(billNo);
        outMaster.setState(WareTaskConstant.SO_STATE_OUTED);
        outMaster.setCreateUserId(currentUser.getUserId());
        outMaster.setCreateUserName(currentUser.getUserName());
        this.save(outMaster);
        for (OutDetail outDetail : outDetails) {
            outDetail.setBillNo(billNo);
        }
        outDetailService.updateBatchById(outDetails);
        return billNo;
    }

    @Override
    public String createOutBill(PickTask pickTask, double pickQty, CurrentUser currentUser) {
        //Step1.生成出库任务明细
        OutDetail outDetail = new OutDetail(pickTask);

        //Step2.判断是否已有出库单
        Integer soMasterId = pickTask.getSoMasterId();
        QueryWrapper<OutMaster> qw = new QueryWrapper<>();
        qw.eq("so_master_id", soMasterId);
//        qw.eq("state", WareTaskConstant.OUT_STATE_INIT);
        OutMaster outMaster = this.getOne(qw);

        if (ObjectUtil.isNotNull(outMaster)) {
            //已生成，且没有发货
            List<OutDetail> list = outDetailService.list(new QueryWrapper<OutDetail>()
                    .eq("bill_no", outMaster.getBillNo()).orderByDesc("line_no"));
            Integer curLineNo = 1;
            if (CollectionUtil.isNotEmpty(list)) {
                curLineNo = list.get(0).getLineNo() + 1;
            }
            String detailNo = outMaster.getBillNo() + "-" + curLineNo;
            outDetail.setDetailNo(detailNo);
            outDetail.setLineNo(curLineNo);
            outDetail.setBillNo(outMaster.getBillNo());
        } else {
            SoMaster soMaster = soMasterService.getById(soMasterId);
            outMaster = new OutMaster(soMaster);
            String billNo = codeRuleService.generateCodeByRedis("Out");
            outMaster.setBillNo(billNo);
            outMaster.setCreateTime(LocalDateTime.now());
            outMaster.setCreateUserId(currentUser.getUserId());
            outMaster.setCreateUserName(currentUser.getUserName());
            this.save(outMaster);

            outDetail.setBillNo(billNo);
            outDetail.setLineNo(1);
            outDetail.setDetailNo(billNo + "-" + 1);
        }
        outDetail.setDeliveryQuantity(pickQty);
        outDetailService.save(outDetail);
        return outMaster.getBillNo();
    }

    @Override
    public void confirmOutBill(OutMaster outMaster, CurrentUser currentUser) {
        SoMaster soMaster = soMasterService.getById(outMaster.getSoMasterId());
        //Step1.出库单处理
        List<OutDetail> outDetails = outDetailService.getListByField("bill_no", outMaster.getBillNo());
        outMaster.setState(WareTaskConstant.OUT_STATE_CLOSE);
        outMaster.setOutTime(LocalDateTime.now());
        outMaster.setOutUserId(currentUser.getUserId());
        outMaster.setOutUserName(currentUser.getUserName());

        List<OutDetail> outDetailList = new ArrayList<>();
        //Step2.根据出库单生成库存事务
        for (OutDetail outDetail : outDetails) {
            if(ObjectUtil.notEqual(WareTaskConstant.OUT_STATE_CLOSE, outDetail.getState())){
                this.toStockRequest(outMaster, outDetail, currentUser);

                outDetail.setState(WareTaskConstant.OUT_STATE_CLOSE);

                //Step3.1 回写上游单据
                //拣货任务
                PickTask pickTask = pickTaskService.getById(outDetail.getPickTaskId());
                pickTask.setSeededQuantity(pickTask.getSeededQuantity() + outDetail.getDeliveryQuantity());
                //[出库任务明细]
                SoDetail soDetail = soDetailService.getById(outDetail.getSoDetailId());
                soDetail.setDeliveryQuantity(soDetail.getDeliveryQuantity() + outDetail.getDeliveryQuantity());
                if (soDetail.getDeliveryQuantity() >= soDetail.getOrderQuantity()) {
                    soDetail.setState(WareTaskConstant.OUT_STATE_CLOSE);
                }
                soDetailService.updateById(soDetail);
                pickTaskService.updateById(pickTask);
                outDetailList.add(outDetail);
            }
        }
        //Step3.2 回写上游单据[出库任务]状态

        List<SoDetail> soDetails = soDetailService.findByBillNo(soMaster.getBillNo());
        boolean flag = true;
        for (SoDetail soDetail : soDetails) {
            if (ObjectUtil.notEqual(WareTaskConstant.OUT_STATE_CLOSE, soDetail.getState())) {
                flag = false;
                break;
            }
        }
        if (flag) {
            soMaster.setState(WareTaskConstant.OUT_STATE_CLOSE);
        }

        //Step4.扣减库存
        List<Integer> invList = outDetails.stream().map(OutDetail::getInventoryId).collect(Collectors.toList());
        inventoryService.removeByIds(invList);

        outDetailService.updateBatchById(outDetails);
        this.updateById(outMaster);
        soMasterService.updateById(soMaster);
        //Step5.回传ERP
        if ("jy".equals(name)) {
        //聚源回传ERP
//            extractedJY(pickTaskList);
        } else {
//            sendToERP(soMaster,outDetailList);
        }
    }

    private void extractedJY(List<PickTask> list) {
        //Step0. 初始化数据
        List<Integer> soDetailIds = list.stream().map(item -> item.getSoDetailId()).collect(Collectors.toList());
        List<String> areaCodes = list.stream().map(PickTask::getAreaCode).collect(Collectors.toList());
        List<SoDetail> soDetails = soDetailService.listByIds(soDetailIds);
        List<AreaInfo> areaInfos = areaInfoService.list(new QueryWrapper<AreaInfo>().in("area_code", areaCodes));
        //Step1.仓库,任务单详情转为Map
        Map<String, AreaInfo> areaMap = convertMap(areaInfos, AreaInfo::getAreaCode);
        Map<Integer, SoDetail> soDetailMap = convertMap(soDetails, SoDetail::getSoDetailId);
        List<SoDetail> detailList = new ArrayList<>();
        for (PickTask pickTask : list) {
            SoDetail soDetail = soDetailMap.get(pickTask.getSoDetailId());
            soDetail.setQty(pickTask.getPickQuantity());
            soDetail.setStockId(Optional.ofNullable(areaMap.get(pickTask.getAreaCode())).map(item -> item.getErpAreaId()).orElse(null));
            detailList.add(soDetail);
        }
        SoDetail soDetail = detailList.listIterator().next();
        SoMaster soMaster = soMasterService.getOne(new QueryWrapper<SoMaster>().eq("bill_no", soDetail.getBillNo()));
        //Step2回传ERP
        strategyErpService.resolveSo(soMaster, detailList);
    }

    @Autowired
    private ErpRecordService erpRecordService;

//    private void sendToERP(SoMaster soMaster, List<OutDetail> outDetails) {
//        //erp回传
//        //2003 采购退货 2004 销售出货 2005 生产领料 2006 调拨出库
//        //出库
//        Integer soType = soMaster.getSoType();
//        outDetails.stream().forEach(outDetail -> {
//            SoDetail detail = soDetailMapper.selectById(outDetail.getSoDetailId());
//
//            Double deliveryQuantity = outDetail.getDeliveryQuantity();
//            PickTask pickTask = pickTaskService.getById(outDetail.getPickTaskId());
//            if (soType == null) {
//                return;
//            }
//             if (ObjectUtil.equals(soType, 2004)) {//2004 销售出货
//                List<SalesShipmentVo> salesShipmentVos = new ArrayList<SalesShipmentVo>();
//                SalesShipmentVo salesShipmentVo = new SalesShipmentVo();
//                salesShipmentVo.setShipPlanNo(detail.getBillNo());//出货计划单号
//                salesShipmentVo.setShipPlanLineNo(detail.getErpLineNo());//出货计划单行号
//                salesShipmentVo.setShipQty(detail.getPickQuantity());//出货数量
//                String areaCode = pickTask.getAreaCode();
//                salesShipmentVo.setWhCode(areaCode);//存储地点
//                salesShipmentVos.add(salesShipmentVo);
//                Map<String, Object> soMap = new HashMap<>();
//                Map<String, Object> requestMap = new HashMap<>();
//                try {
//                    requestMap.put("data", salesShipmentVos);
//                    requestMap.put("msg", "请求");
//                    requestMap.put("code", 200);
//                    erpRecordService.erpLog(requestMap, ErpOutConstant.ERP_OUT_TYPE_SALES);
//                    soMap = doPostOrGet(ErpOutConstant.ERP_OUT_RETURL_SALES, JSONObject.toJSONString(salesShipmentVos));
//                    if (soMap.get("code") == null || !"200".equals(soMap.get("code").toString())) {
//                        throw new ServiceException(CommonCode.SERVER_INERNAL_ERROR, "销售回传失败,具体原因:" + soMap.get("msg").toString());
//                    }
//                } finally {
//                    erpRecordService.erpLog(soMap, ErpOutConstant.ERP_OUT_TYPE_SALES);
//                }
//            } else if (ObjectUtil.equal(ErpOutConstant.ERP_OUT_TYPE_PICK, soType)) {//2005 生产领料
//                List<ProductionPicking> productionPickings = new ArrayList<>();
//                ProductionPicking productionPicking = new ProductionPicking();
//                productionPicking.setMo(detail.getMo());//生产订单ID
//                productionPicking.setMoPick(Long.parseLong(detail.getMoPick()));//生产订单备料ID
//                productionPicking.setIssueQty(detail.getPickQuantity());//应发数量
//                String areaCode = pickTask.getAreaCode();
//                productionPicking.setWhCode(areaCode);//存储地点编码
//                productionPickings.add(productionPicking);
//                Map<String, Object> soMap = new HashMap<>();
//                try {
//                    soMap = doPostOrGet(ErpOutConstant.ERP_OUT_RETURL_PICK, JSONObject.toJSONString(productionPickings));
//                    if (soMap.get("code") == null || !"200".equals(soMap.get("code").toString())) {
//                        throw new ServiceException(CommonCode.SERVER_INERNAL_ERROR, "生产领料回传失败,具体原因：" + soMap.get("msg").toString());
//                    }
//                } finally {
//                    erpLog(soMap, soType.intValue());
//                }
//
//            } else if (ObjectUtil.equals(soType.intValue(), ErpOutConstant.ERP_OUT_TYPE_ZF)) {//2007
//                //杂发回调
//
//            }
//        });
//    }

    /**
     * 添加回传日志信息
     *
     * @param returnMap
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
    public void erpLog(Map<String, Object> returnMap, int type) {
        //添加回传日志信息
        ErpBackRecord erpBackRecord = new ErpBackRecord();
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String tim = df.format(new Date());
        erpBackRecord.setCreateTime(tim);
        erpBackRecord.setParam(returnMap.get("data").toString());
        erpBackRecord.setMsg(returnMap.get("msg").toString());
        erpBackRecord.setCode(returnMap.get("code").toString());
        erpBackRecord.setType(type+"" );
        int insert = erpBackRecordMapper.insert(erpBackRecord);
        if (insert <= 0) {
            throw new ServiceException(CommonCode.SERVER_INERNAL_ERROR, "添加日志失败");
        }
    }

    /**
     * 调用地第三方接口
     *
     * @param pathUrl 地址
     * @param data    参数
     * @return
     */
    public static Map<String, Object> doPostOrGet(String pathUrl, String data) {
        System.out.println("================================================");
        System.out.println(data);
        System.out.println("================================================");
        OutputStreamWriter out = null;
        BufferedReader br = null;
        String result = "";
        Map<String, Object> map = new HashMap<>();
        try {
            URL url = new URL(pathUrl);
            //打开和url之间的连接
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            //请求方式
            conn.setRequestMethod("POST");
            //conn.setRequestMethod("GET");

            //设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
            conn.setRequestProperty("Content-Type", "application/json;charset=utf-8");

            //DoOutput设置是否向httpUrlConnection输出，DoInput设置是否从httpUrlConnection读入，此外发送post请求必须设置这两个
            conn.setDoOutput(true);
            conn.setDoInput(true);

            /**
             * 下面的三句代码，就是调用第三方http接口
             */
            //获取URLConnection对象对应的输出流
            out = new OutputStreamWriter(conn.getOutputStream(), "UTF-8");
            //发送请求参数即数据
            out.write(data);
            //flush输出流的缓冲
            out.flush();

            /**
             * 下面的代码相当于，获取调用第三方http接口后返回的结果
             */
            //获取URLConnection对象对应的输入流
            InputStream is = conn.getInputStream();
            //构造一个字符流缓存
            br = new BufferedReader(new InputStreamReader(is));
            String str = "";
            while ((str = br.readLine()) != null) {
                result += str;
            }
            map = JSON.parseObject(result);
            System.out.println(result);
            //关闭流
            is.close();
            //断开连接，disconnect是在底层tcp socket链接空闲时才切断，如果正在被其他线程使用就不切断。
            conn.disconnect();

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (br != null) {
                    br.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return map;
    }

    @Override
    public String createOutBillBySoMaster(SoMaster soMaster, CurrentUser currentUser) {
        // 增加生成出库单数据
        //Step1.生成出库单out_master
        OutMaster outMaster = new OutMaster(soMaster);
        // 出库单
        String billNo = codeRuleService.generateCode("OUT");
        outMaster.setBillNo(billNo);
        outMaster.setState(WareTaskConstant.SO_STATE_OUTED);
        outMaster.setCreateUserId(currentUser.getUserId());
        outMaster.setCreateUserName(currentUser.getUserName());
        this.save(outMaster);
        // 出库单明细
        // 查询出对应的拣货任务--每一条拣货任务对应一条出库单明细
        List<PickTask> pickTasks = pickTaskService.list(new QueryWrapper<PickTask>().eq("so_master_id", soMaster.getSoMasterId()));
        List<OutDetail> outDetailList = new ArrayList<OutDetail>();
        for(PickTask pickTask:pickTasks){
            OutDetail outDetail=new OutDetail();
            // 单号
            outDetail.setBillNo(outMaster.getBillNo());
            // 明细单号
            outDetail.setDetailNo(pickTask.getPickTaskCode());
            // 状态 2 发货
            outDetail.setState(2);
            // 物料编码
            outDetail.setItemCode(pickTask.getItemCode());
            outDetail.setItemName(pickTask.getItemName());
            outDetail.setImgUrl(pickTask.getImgUrl());
            // 包装信息
            outDetail.setPackDetailId(pickTask.getPackDetailId());
            outDetail.setPackDescribe(pickTask.getPackDescribe());
            // 订货数
            outDetail.setDeliveryQuantity(pickTask.getPickQuantity());
            // 容器
            outDetail.setBoxCode(pickTask.getBoxCode());
            // 库位编码
            outDetail.setCellCode(pickTask.getCellCode());
            // 批次号
            outDetail.setBatchName(pickTask.getBatchName());
            // 批次Id
            outDetail.setBatchId(pickTask.getBatchId());
            // 出库任务明细Id
            outDetail.setSoDetailId(pickTask.getSoDetailId());
            outDetailList.add(outDetail);
        }
        // 批量插入
        outDetailService.saveBatch(outDetailList);
        return billNo;
    }

    @Override
    public void signConfirm(MultipartFile file, String outBillCode) throws IOException {
        String fileName = outBillCode;
        String filePath = "d:/wms/";
        File dest = new File(filePath + fileName + ".png");
        // 检测是否存在目录
        if (!dest.getParentFile().exists()) {
            dest.getParentFile().mkdirs();
        }
        try {
            file.transferTo(dest);
        } catch (IllegalStateException | IOException e) {
            e.printStackTrace();
        }

        OutMaster outMaster = this.getOneByField("bill_no", outBillCode);
        outMaster.setSignTime(LocalDateTimeUtil.now());
        outMaster.setState(WareTaskConstant.OUT_STATE_SING);
        outMaster.setMemo("签收成功!!~");
        this.updateById(outMaster);
    }

    @Override
    public void sendWeiWaiToErp(SoMaster soMaster, String supplierCode) {
        List<SoDetail> soDetails = soDetailService.getListByField("bill_no", soMaster.getBillNo());
        List<AllocatingOutboundVo> allocatingOutboundVoList = new ArrayList<>();
        AllocatingOutboundVo allocatingOutboundVo = new AllocatingOutboundVo();
        allocatingOutboundVo.setDocType("TransIn004");

        List<LinesVo> linesVos = new ArrayList<>();

        for (SoDetail soDetail : soDetails) {
            if (soDetail.getDeliveryQuantity() == 0) {
                continue;
            }
            if(soDetail.getDeliveryQuantity().equals(soDetail.getQtyTrans())) {
                continue;
            }
            LinesVo linesVo = new LinesVo();
            linesVo.setItemCode(soDetail.getItemCode());//料品编码
            linesVo.setOutWhCode("ZP01");//调出存储地点编码
            linesVo.setInWhCode("WW01");//调入存储地点编码(委外存储地点编码)
            linesVo.setStoreQty(soDetail.getDeliveryQuantity() - soDetail.getQtyTrans());//调拨数量 = 已拣货数量 - 已发货数量
            linesVo.setSupplierCode(supplierCode);
            linesVos.add(linesVo);

            //更新ERP同步数量
            soDetail.setQtyTrans(soDetail.getDeliveryQuantity());
        }
        if (CollectionUtil.isEmpty(linesVos)) {
            return;
        }
        allocatingOutboundVo.setLines(linesVos);
        allocatingOutboundVoList.add(allocatingOutboundVo);

        Map<String, Object> soMap = new HashMap<>();
        Map<String, Object> requestMap = new HashMap<>();
        try {
            requestMap.put("data", allocatingOutboundVoList);
            requestMap.put("msg", "请求");
            requestMap.put("code", 200);
//            erpRecordService.erpLog(requestMap, ErpOutConstant.ERP_OUT_TYPE_OUTSOURCE);
            soMap = doPostOrGet(ErpOutConstant.ERP_OUT_RETURL_OUTSOURCE, JSONObject.toJSONString(allocatingOutboundVoList));
            if (soMap.get("code") == null || !"200".equals(soMap.get("code").toString())) {
                throw new ServiceException(CommonCode.SERVER_INERNAL_ERROR, "委外出库回传失败，具体原因:" + soMap.get("msg").toString());
            }
            //更新ERP的同步状态
            soMaster.setErpState(1);
            soMasterService.updateById(soMaster);
            soDetailService.updateBatchById(soDetails);
        } finally {
//            erpRecordService.erpLog(soMap, ErpOutConstant.ERP_OUT_TYPE_OUTSOURCE);
        }
    }

    @Override
    public void sendShengChanToErp(SoMaster soMaster) {
        List<SoDetail> soDetails = soDetailService.getListByField("bill_no", soMaster.getBillNo());
        List<AllocatingOutboundVo> allocatingOutboundVoList = new ArrayList<>();
        AllocatingOutboundVo allocatingOutboundVo = new AllocatingOutboundVo();
        allocatingOutboundVo.setDocType("TransIn002");

        List<LinesVo> linesVos = new ArrayList<>();

        for (SoDetail soDetail : soDetails) {
            if (soDetail.getDeliveryQuantity() == 0) {
                continue;
            }
            if(soDetail.getDeliveryQuantity().equals(soDetail.getQtyTrans())) {
                continue;
            }
            LinesVo linesVo = new LinesVo();
            linesVo.setItemCode(soDetail.getItemCode());//料品编码
            linesVo.setOutWhCode("ZP01");//调出存储地点编码
            linesVo.setInWhCode("ZP05");//调入存储地点编码(线边仓存储地点编码)
            linesVo.setStoreQty(soDetail.getDeliveryQuantity() - soDetail.getQtyTrans());//调拨数量
            linesVos.add(linesVo);

            soDetail.setQtyTrans(soDetail.getDeliveryQuantity());
        }
        if (CollectionUtil.isEmpty(linesVos)) {
            return;
        }
        allocatingOutboundVo.setLines(linesVos);
        allocatingOutboundVoList.add(allocatingOutboundVo);

        Map<String, Object> soMap = new HashMap<>();
        Map<String, Object> requestMap = new HashMap<>();
        try {
            requestMap.put("data", allocatingOutboundVoList);
            requestMap.put("msg", "请求");
            requestMap.put("code", 200);
//            erpRecordService.erpLog(requestMap, ErpOutConstant.ERP_OUT_TYPE_PICK);
            soMap = doPostOrGet(ErpOutConstant.ERP_OUT_RETURL_PICK, JSONObject.toJSONString(allocatingOutboundVoList));
            if (soMap.get("code") == null || !"200".equals(soMap.get("code").toString())) {
                throw new ServiceException(CommonCode.SERVER_INERNAL_ERROR, "委外出库回传失败，具体原因:" + soMap.get("msg").toString());
            }
            //更新ERP的同步状态
            soMaster.setErpState(1);
            soMasterService.updateById(soMaster);
            soDetailService.updateBatchById(soDetails);
        } finally {
//            erpRecordService.erpLog(soMap, ErpOutConstant.ERP_OUT_TYPE_PICK);
        }
    }

    @Override
    public void sendZafaToErp(SoMaster soMaster) {
        List<SoDetail> soDetails = soDetailService.getListByField("bill_no", soMaster.getBillNo());
        List<MiscellaneousVo> miscellaneousVos = new ArrayList<>();
        MiscellaneousVo miscellaneousVo = new MiscellaneousVo();
        miscellaneousVo.setDocType(soMaster.getUda1());
        List<LinesDtoVo> linesList = new ArrayList<>();



        for (SoDetail soDetail : soDetails) {
            List<PickTask> pickTasks = pickTaskService.getListByField("so_detail_id", soDetail.getSoDetailId());
            LinesDtoVo line = new LinesDtoVo();
            line.setItemCode(soDetail.getItemCode());
            line.setWhCode(pickTasks.get(0).getAreaCode());
            line.setStoreQty(soDetail.getDeliveryQuantity());//杂收数量
            linesList.add(line);

            soDetail.setQtyTrans(soDetail.getDeliveryQuantity());
        }

        miscellaneousVo.setLines(linesList);
        miscellaneousVos.add(miscellaneousVo);
        Map<String, Object> returnMap = new HashMap<>();
        Map<String, Object> requestMap = new HashMap<>();
        try {
//            requestMap.put("data", miscellaneousVos);
//            requestMap.put("msg", "请求");
//            requestMap.put("code", 200);
//            erpRecordService.erpLog(requestMap, ErpOutConstant.ERP_OUT_TYPE_ZF);
//            returnMap = doPostOrGet(ErpOutConstant.ERP_OUT_RETURL_ZF, JSONObject.toJSONString(miscellaneousVos));
//            if (returnMap.get("code") == null || !"200".equals(returnMap.get("code").toString())) {
//                throw new ServiceException(CommonCode.SERVER_INERNAL_ERROR, "杂出出库回传失败，具体原因:" + returnMap.get("msg").toString());
//            }
//
//            //更新ERP的同步状态
//            soMaster.setErpState(1);
//            soMasterService.updateById(soMaster);
        } finally {
//            erpRecordService.erpLog(returnMap, ErpOutConstant.ERP_OUT_TYPE_ZF);
        }
    }


    /**
     * 根据出库单明细生成库存事务
     * @param outDetail 出库单明细
     * @return InventoryTransact
     */
    private InventoryTransact toStockRequest(OutMaster outMaster, OutDetail outDetail, CurrentUser currentUser) {
        InventoryTransact inventoryTransact = new InventoryTransact();
        //Step1.准备数据
        //仓库
        inventoryTransact.setWareId(outMaster.getWareId());
        inventoryTransact.setWareName(outMaster.getWareName());
        //货主
        inventoryTransact.setToOrganizationId(outMaster.getOrganizationId());
        inventoryTransact.setToOrganizationName(outMaster.getOrganizationName());
        //库位
        inventoryTransact.setFromCellCode(outDetail.getCellCode());
        //容器
        inventoryTransact.setFromBoxCode(outDetail.getBoxCode());
        //物料
        inventoryTransact.setItemCode(outDetail.getItemCode());
        inventoryTransact.setItemName(outDetail.getItemName());
        //批次
        inventoryTransact.setFromBatchId(outDetail.getBatchId());
        inventoryTransact.setFromBatchName(outDetail.getBatchName());
        //数量
        inventoryTransact.setFromQuantity(outDetail.getDeliveryQuantity());
        //包装 转换率
        inventoryTransact.setFromPackDetailId(outDetail.getPackDetailId());
        inventoryTransact.setFromPackDescribe(outDetail.getPackDescribe());
        //创建人 时间
        inventoryTransact.setCreateUserId(currentUser.getUserId());
        inventoryTransact.setCreateUserName(currentUser.getUserName());
        inventoryTransact.setCreateTime(DateUtil.now());
        //事务类型
        inventoryTransact.setTransactType(InventoryConstant.INVENTORY_TYPE_OUT);
        //来源单据号
        inventoryTransact.setBillNo(outMaster.getBillNo());

        //Step2.保存，返回
        inventoryTransactService.save(inventoryTransact);
        return inventoryTransact;
    }
}
